package bean.managed;

import bean.managed.util.JsfUtil;
import bean.session.RawMaterialEntityFacade;
import bean.session.RawMaterialPurchaseOrderEntityFacade;
import bean.session.RawMaterialPurchaseOrderReportEntityFacade;
import bean.session.RawMaterialQuotationFacade;
import bean.session.VendorProductPriceEntityFacade;
import entity.VendorEntity;

import bean.session.VendorEntityFacade;


import entity.AddressEntity;
import entity.RawMaterialPurchaseOrderEntity;

import entity.RawMaterialQuotationEntity;

import java.io.Serializable;
import java.util.ArrayList;

import java.util.Collection;
import java.util.Date;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.SelectItem;
import managedbean.AbstractBacking;
import org.primefaces.event.RateEvent;

import org.primefaces.event.SelectEvent;

import type.AddressType;
import type.RawMaterialPurchaseOrderStatus;

import type.RawMaterialQuotationType;

@ManagedBean(name = "rawMaterialPurchaseOrderEntityController")
@SessionScoped
public class RawMaterialPurchaseOrderEntityController extends AbstractBacking implements Serializable {

    //////////////////////////////////////////
    //private List<RawMaterialEntity> allRMEntityList;
    //private List<RawMaterialEntity> userRightsEntityList;
    //this quotation has the raw material ,true ,otherwise false
    private VendorEntity vendor;
    @EJB
    private bean.session.RawMaterialEntityFacade facade;
    @EJB
    private bean.session.VendorProductPriceEntityFacade vfacade;
    @EJB
    private bean.session.VendorEntityFacade ejbFacade;

    public SelectItem[] getUnfulfilledRMPurchaseOrdersAvailableSelectOne() {
        return JsfUtil.getSelectItems(rpFacade.unfulfilledPurchaseOrders(), true);
    }

    public VendorProductPriceEntityFacade getVfacade() {
        return vfacade;
    }

    public void setVfacade(VendorProductPriceEntityFacade vfacade) {
        this.vfacade = vfacade;
    }

    public RawMaterialEntityFacade facade() {
        return facade;
    }

    public void setFacade(RawMaterialEntityFacade facade) {
        this.facade = facade;
    }

    public VendorEntity getVendor() {
        if (getLoginVendor() != null) {
            return getLoginVendor();
        }
        return null;
    }
    private List entrySet;

    public List getEntrySet() {
        entrySet = new ArrayList(currRpo.getShip().entrySet());
        Iterator it = entrySet.iterator();

        return entrySet;
    }

    public void setEntrySet(List entrySet) {
        this.entrySet = entrySet;
    }

    public void setVendor(VendorEntity vendor) {
        this.vendor = vendor;
    }
    private VendorEntity selectedVendor;
//////////////////////////////////////////  
    private RawMaterialQuotationEntity selectedRmq;

    public RawMaterialQuotationEntity getSelectedRmq() {
        return selectedRmq;
    }

    public void setSelectedRmq(RawMaterialQuotationEntity selectedRmq) {
        this.selectedRmq = selectedRmq;
    }
    private List<RawMaterialQuotationEntity> RmqPurchaseList = new ArrayList<RawMaterialQuotationEntity>();

    public List<RawMaterialQuotationEntity> getRmqPurchaseList() {
        return RmqPurchaseList;
    }

    public void setRmqPurchaseList(List<RawMaterialQuotationEntity> RmqPurchaseList) {
        this.RmqPurchaseList = RmqPurchaseList;
    }

    public VendorEntity getSelectedVendor() {
        return selectedVendor;
    }

    public void setSelectedVendor(VendorEntity selectedVendor) {
        this.selectedVendor = selectedVendor;
    }
    private VendorEntity current;

    public VendorEntityFacade getEjbFacade() {
        return ejbFacade;
    }

    public void setEjbFacade(VendorEntityFacade ejbFacade) {
        this.ejbFacade = ejbFacade;
    }

    public RawMaterialPurchaseOrderEntityController() {
    }
    @EJB
    private bean.session.RawMaterialQuotationFacade rqFacade;
    @EJB
    private bean.session.RawMaterialPurchaseOrderEntityFacade rpFacade;

    public RawMaterialPurchaseOrderEntityFacade getRpFacade() {
        return rpFacade;
    }

    public void setRpFacade(RawMaterialPurchaseOrderEntityFacade rpFacade) {
        this.rpFacade = rpFacade;
    }

    public RawMaterialQuotationFacade getRqFacade() {
        return rqFacade;
    }

    public void setRqFacade(RawMaterialQuotationFacade rqFacade) {
        this.rqFacade = rqFacade;
    }
    private Collection<RawMaterialQuotationEntity> rmqs;

    public Collection<RawMaterialQuotationEntity> getRmqs() {
        return getRqFacade().getQuotedQuotation();
    }

    public void setRmqs(Collection<RawMaterialQuotationEntity> rmqs) {
    }
    //in the purchase list or not

    public boolean checkPurchaseList(RawMaterialQuotationEntity r1) {
        for (RawMaterialQuotationEntity r : getRmqPurchaseList()) {
            if ((r1.getRawMaterial().getProductName().equalsIgnoreCase(r.getRawMaterial().getProductName()))
                    && (r.getValidity().equals(r1.getValidity()))) {
                System.out.println();
                return true;
            }
        }
        return false;
    }

    public Collection<RawMaterialQuotationEntity> updateRejectedQuotation() {
        Collection<RawMaterialQuotationEntity> result = new ArrayList<RawMaterialQuotationEntity>();

        for (RawMaterialQuotationEntity r : getRmqs()) {
            System.out.println(r.getPrice() + "kkkkk");
            if (checkPurchaseList(r)) {
                result.add(r);
            }
        }
        return result;
    }

    public String createPurchase() {

        for (RawMaterialQuotationEntity rmq : getRmqPurchaseList()) {
            VendorEntity v = rmq.getVendor();
            rmq.setType(RawMaterialQuotationType.accepted);
            getRqFacade().edit(rmq);
            //Collection<RawMaterialQuotationEntity> rmqs =new ArrayList<RawMaterialQuotationEntity>();
            RawMaterialPurchaseOrderEntity rpo = new RawMaterialPurchaseOrderEntity();
            rpo.setRmq(rmq);
            rpo.setAmountLeft(rmq.getQuantity());
            rpo.setPrice(rmq.getPrice());
            rpo.setQuantity(rmq.getQuantity());
            rpo.setFigureCost(rmq.getQuantity() * rmq.getPrice());
            rpo.setCost(rmq.getCost());
            rpo.setStatus(RawMaterialPurchaseOrderStatus.pending);
            rpo.setDateConfirmed(new Date());
            rpo.setCreatedBy(getCurrentUser());
            getRpFacade().create(rpo);
            v.getRawMaterialPurchases().add(rpo);

            getEjbFacade().edit(v);

        }

        Collection<RawMaterialQuotationEntity> result = updateRejectedQuotation();
        if (result.size() != 0) {
            for (RawMaterialQuotationEntity r : result) {

                r.setType(RawMaterialQuotationType.rejected);
                getRqFacade().edit(r);
            }
        }
        RmqPurchaseList.clear();

        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("Purchased Order issued.Rejected Quotation updated ", "Purchased Order issued.Rejected Quotation updated "));
        return "PriceComparison?faces-redirect=true";
    }
    //pending order
    private Collection<RawMaterialPurchaseOrderEntity> rpos;
    private RawMaterialPurchaseOrderEntity currPurchaseOrder;

    public RawMaterialPurchaseOrderEntity getCurrPurchaseOrder() {
        return currPurchaseOrder;
    }

    public void setCurrPurchaseOrder(RawMaterialPurchaseOrderEntity currPurchaseOrder) {
        this.currPurchaseOrder = currPurchaseOrder;
    }

    public RawMaterialPurchaseOrderEntity getSelectedPurchaseOrder() {
        return selectedPurchaseOrder;
    }

    public void setSelectedPurchaseOrder(RawMaterialPurchaseOrderEntity selectedPurchaseOrder) {
        this.selectedPurchaseOrder = selectedPurchaseOrder;
    }
    private RawMaterialPurchaseOrderEntity selectedPurchaseOrder;

    public Collection<RawMaterialPurchaseOrderEntity> getRpos() {
        return getRpFacade().getPendingOrder();
    }

    public void setRpos(Collection<RawMaterialPurchaseOrderEntity> rpos) {
        this.rpos = rpos;
    }

    public String purchaseOrderSelect(SelectEvent event) {

        currPurchaseOrder = selectedPurchaseOrder;



        return "OrderDetail?faces-redirect=true";
    }

    public String purchaseOrderSelect1(SelectEvent event) {

        currPurchaseOrder = selectedPurchaseOrder;



        return "MaintainOrder?faces-redirect=true";
    }
    //all purchase order
    private Collection<RawMaterialPurchaseOrderEntity> rposs;

    public Collection<RawMaterialPurchaseOrderEntity> getRposs() {
        return getRpFacade().getPendingOrder();
    }

    public void setRposs(Collection<RawMaterialPurchaseOrderEntity> rposs) {
        this.rposs = rposs;
    }
    //amount rm shipped
    private double amount;

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }
    //day receive the product 
    private Date validity;

    public Date getValidity() {
        return validity;
    }

    public void setValidity(Date validity) {
        this.validity = validity;
    }

    @FacesConverter(forClass = RawMaterialPurchaseOrderEntity.class)
    public static class RawMaterialPurchaseOrderControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            RawMaterialPurchaseOrderEntityController controller = (RawMaterialPurchaseOrderEntityController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "rawMaterialPurchaseOrderEntityController");
            return controller.rpFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof RawMaterialPurchaseOrderEntity) {
                RawMaterialPurchaseOrderEntity o = (RawMaterialPurchaseOrderEntity) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + CompletedGoodsEntityController.class.getName());
            }
        }
    }

    public String editOrder() {
        // total quantity of this order
        double total = currPurchaseOrder.getQuantity();
        Double filled = new Double(0);
        HashMap cur = currPurchaseOrder.getShip();
        Collection c = cur.values();

        for (Object key : cur.keySet()) {
            filled += (Double) cur.get(key);
        }

        //the amount has already been filled for this order 
        double fill = filled.doubleValue();



        //amount is the quantity of this particular shipment
        if (amount + fill < total) {
            cur.put(validity, new Double(amount));
            double left = total - amount - fill;
            currPurchaseOrder.setShipAmount(cur);
            currPurchaseOrder.setStatus(RawMaterialPurchaseOrderStatus.partlyfilled);
            currPurchaseOrder.setAmountLeft(left);
            getRpFacade().edit(currPurchaseOrder);

            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage("Purchase Order Updated ", "The amount left is " + left + " out of " + total));
        } else if (amount + fill == total) {
            cur.put(validity, new Double(amount));
            currPurchaseOrder.setDateConfirmed(validity);
            currPurchaseOrder.setStatus(RawMaterialPurchaseOrderStatus.fulfilled);
            currPurchaseOrder.setAmountLeft(0);
            currPurchaseOrder.setShipAmount(cur);
            getRpFacade().edit(currPurchaseOrder);
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage("Purchase Order Updated ", "Order filled entirely"));
        } else {
            
            
            
            FacesContext context = FacesContext.getCurrentInstance();
       
         
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "This is absurd.Check it again!!", "U pay for " + total + " and they ship more than that??? "));

        }
        validity = null;
        amount = 0;

        return "main?faces-redirect=true";
    }
    //for rating order
    private Collection<RawMaterialPurchaseOrderEntity> fulfilledRposs;

    public Collection<RawMaterialPurchaseOrderEntity> getFulfilledRposs() {
        return getRpFacade().getSettledOrder();
    }

    public void setFulfilledRposs(Collection<RawMaterialPurchaseOrderEntity> fulfilledRposs) {
        this.fulfilledRposs = fulfilledRposs;
    }
    private RawMaterialPurchaseOrderEntity currRpo;

    public RawMaterialPurchaseOrderEntity getCurrRpo() {
        return currRpo;
    }

    public void setCurrRpo(RawMaterialPurchaseOrderEntity currRpo) {
        this.currRpo = currRpo;
    }
    private RawMaterialPurchaseOrderEntity selectedRpo;

    public RawMaterialPurchaseOrderEntity getSelectedRpo() {
        return selectedRpo;
    }

    public void setSelectedRpo(RawMaterialPurchaseOrderEntity selectedRpo) {
        this.selectedRpo = selectedRpo;
    }

    public String RPOSelect(SelectEvent event) {
        currRpo = selectedRpo;
        return "RateOrder?faces-redirect=true";

    }
    @EJB
    private bean.session.RawMaterialPurchaseOrderReportEntityFacade rmpo;

    public RawMaterialPurchaseOrderReportEntityFacade getRmpo() {
        return rmpo;
    }

    public void setRmpo(RawMaterialPurchaseOrderReportEntityFacade rmpo) {
        this.rmpo = rmpo;
    }

    public void handleRate(RateEvent rateEvent) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Rate Event", "You rated:" + (int) rateEvent.getRating());
        currRpo.setStar((double) rateEvent.getRating());


        getRpFacade().edit(currRpo);


        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public String back() {
        currRpo.setStatus(RawMaterialPurchaseOrderStatus.reviewed);
        currRpo.setNote(note);
        getRpFacade().edit(currRpo);
        VendorEntity v = currRpo.getRmq().getVendor();

        Collection<RawMaterialPurchaseOrderEntity> rawMaterialPurchases = v.getRawMaterialPurchases();


        double total = 0;
        int count = 0;
        for (RawMaterialPurchaseOrderEntity r : rawMaterialPurchases) {

            if (r.getStatus().equals(RawMaterialPurchaseOrderStatus.reviewed)) {

                total += r.getStar();
                count++;
            }
        }
        if (rawMaterialPurchases.size() != 0) {
            v.setStar(Round((double) (total / count), 2));
            System.out.println((double) (total / count) + "ffffffffff");
            getEjbFacade().edit(v);
        }
        note = "";
        currRpo = null;
        return "PastOrder?faces-redirect=true";

    }

    public static double Round(double Rval, int Rpl) {
        double p = (double) Math.pow(10, Rpl);
        Rval = Rval * p;
        double tmp = Math.round(Rval);
        return (double) tmp / p;
    }
    private Collection<RawMaterialPurchaseOrderEntity> finishedRpos;

    public Collection<RawMaterialPurchaseOrderEntity> getFinishedRpos() {
        return getRpFacade().getAlreadyReviewedOrder();
    }

    public void setFinishedRpos(Collection<RawMaterialPurchaseOrderEntity> finishedRpos) {
        this.finishedRpos = finishedRpos;
    }
    private String note;

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
    private List scheduleShip;

    public List getScheduleShip() {
        scheduleShip = new ArrayList(currRpo.getScheduleShip().entrySet());
        Iterator it = scheduleShip.iterator();

        return scheduleShip;
    }

    public void setScheduleShip(List scheduleShip) {
        this.scheduleShip = scheduleShip;
    }

    public String done() {
        currPurchaseOrder = null;
        return "AcknowledgeOrder?faces-redirect=true";
    }
    private RawMaterialPurchaseOrderEntity selectedPo;

    public RawMaterialPurchaseOrderEntity getSelectedPo() {
        return selectedPo;
    }

    public void setSelectedPo(RawMaterialPurchaseOrderEntity selectedPo) {
        this.selectedPo = selectedPo;
    }
    private RawMaterialPurchaseOrderEntity curr;

    public RawMaterialPurchaseOrderEntity getCurr() {
        return curr;
    }

    public void setCurr(RawMaterialPurchaseOrderEntity curr) {
        this.curr = curr;
    }

    public String delete1() {

        getRpFacade().originalRemove(selectedPo);
        finishedRpos = null;
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("Order Deleted", "Order Deleted"));
        return "PastOrder";
    }
    private RawMaterialPurchaseOrderEntity po;

    public RawMaterialPurchaseOrderEntity getPo() {
//   if(po==null){po = new RawMaterialPurchaseOrderEntity();
//
//        return po;
//        }
   
    return po;
    }

    public void setPo(RawMaterialPurchaseOrderEntity po) {
        
        this.po = po;
    }
    private List scheduleShip1;

    public List getScheduleShip1() {
        if(po == null)return null;
        scheduleShip1 = new ArrayList(po.getScheduleShip().entrySet());
        Iterator it = scheduleShip1.iterator();

        return scheduleShip1;
    }

    public void setScheduleShip1(List scheduleShip1) {
        this.scheduleShip1 = scheduleShip1;
    }
    private AddressEntity address;
  public boolean isFulfilled(){
      if (currPurchaseOrder == null)return false;
      return currPurchaseOrder.getStatus().equals(RawMaterialPurchaseOrderStatus.fulfilled);
  }
}